﻿/// <reference path="../Script (JScript)/SDK.REST.js"
/// <reference path="../Script (JScript)/SDK.Metadata.Query.vsdoc.js"
/// <reference path="../Script (JScript)/json2.js"


//
// page onload event
//
$(document).ready(function () {

    $(function () {
        $("html, body").mousewheel(function (event, delta) {

            this.scrollLeft -= (delta * 80);
            event.preventDefault();
        });


    });

    DXTools.QuickView.Menu.Initialise();
});








if (typeof (DXTools) == "undefined")
{ DXTools = { __namespace: true }; }
if (typeof (DXTools.QuickView) == "undefined")
{ DXTools.QuickView = { __namespace: true }; }

DXTools.QuickView.MenuItem = function () {

    this.AreaId = "";
    this.AreaTitle = "";
    this.GroupId = ""
    this.GroupTitle = ""
    this.ItemId = ""
    this.ItemTitle
    this.ItemTypeName = "";
    this.ItemTypeCode = "";
    this.Url = "";
    this.ImageUrl;
    __namespace: true;

};


///
/// Main DXTools.QuickView.Menu namespace
///
DXTools.QuickView.Menu = {

    context: null,
    siteMapDoc: null,
    userPrivilegesDoc: null,
    configXmlDoc: null,
    resourceXmlDoc: null,
    menuTree: new Array(),
    securityEnabled: null,
    //layout: null,

    loadCallStackCount: 0,
    processMenuItemCallStackCount: 0,

    //       
    // Initialises menu by loading config, resources and sitemap xml
    //
    Initialise: function () {

        // Grab global context
        this.context = GetGlobalContext();
        //this.layout = qvmLayout;


        this.loadCallStackCount = 3;

        this.RetrieveSiteMap();
        this.RetrieveConfigAndResourceXML();

        if (this.IsSecurityEnabled())
            this.RetrieveUserPrivileges();
        else
            this.LoadActionComplete();


    },

    LoadActionComplete: function () {
        this.loadCallStackCount = this.loadCallStackCount - 1;
        if (this.loadCallStackCount <= 0) {
            this.ProcessSiteMapXML();
        }

    },

    ProcessMenuItemActionComplete: function () {
        this.processMenuItemCallStackCount = this.processMenuItemCallStackCount - 1;
        if (this.processMenuItemCallStackCount <= 0) {
            this.DisplayMenuItems();
        }


    },
    IsSecurityEnabled: function () {
        if (this.securityEnabled == null)
            this.securityEnabled = (this.configXmlDoc != null && this.configXmlDoc.selectSingleNode("//Config/Security[@Enabled='true']") != null)

        return this.securityEnabled;
    }
    ,

    ProcessSiteMapXML: function () {


        var areas = this.siteMapDoc.selectNodes("/SiteMap/Area");
        var allSubAreas = this.siteMapDoc.selectNodes("//SiteMap/Area/Group/SubArea");

        this.processMenuItemCallStackCount = allSubAreas.length;


        // Iterate through Areas
        var areasCount = areas.length;

        for (var a = 0; a < areasCount; a++) {
            var area = areas[a].getAttribute("Id");

            // Check if the item should be excluded
            //if (this.IsExcluded(area, null, null)) {

            //    this.ProcessMenuItemActionComplete();

            //    continue;
            //}


            var areaTitle = "";


            // Grab title value from local resource xml if present
            if (this.resourceXmlDoc != null && this.resourceXmlDoc.selectSingleNode("//Resources/SiteMap/Areas/Area[@Id='" + area + "']") != null) {
                areaTitleTmp = this.resourceXmlDoc.selectSingleNode("//Resources/SiteMap/Areas/Area[@Id='" + area + "']/Titles/Title[@LCID='" + this.context.getOrgLcid() + "']/@Title");
                if (areaTitleTmp != null)
                    areaTitle = areaTitleTmp.nodeValue;
                else {
                    areaTitleTmp = this.resourceXmlDoc.selectSingleNode("//Resources/SiteMap/Areas/Area[@Id='" + area + "']/Titles/Title/@Title");
                    if (areaTitleTmp != null)
                        areaTitle = areaTitleTmp.nodeValue;
                }
            }

            // If title wasn't found in resource xml get it from sitemap
            if (areaTitle == "") {
                var areaTitleTmp = this.siteMapDoc.selectSingleNode("//SiteMap/Area[@Id='" + area + "']/Titles/Title[@LCID='" + this.context.getOrgLcid() + "']/@Title");
                if (areaTitleTmp != null)
                    areaTitle = areaTitleTmp.nodeValue;
                else
                    areaTitle = area;
            }



            // Iterate through groups
            var groups = this.siteMapDoc.selectNodes("//SiteMap/Area[@Id='" + area + "']/Group");
            var groupCount = groups.length;

            for (var g = 0; g < groupCount; g++) {
                var group = groups[g].getAttribute("Id");

                // Check if the item should be excluded
                //if (this.IsExcluded(area, group, null)) {

                //    this.ProcessMenuItemActionComplete();

                //    continue;
                //}

                var groupTitle = "";


                // Grab title value from local resource xml if present
                if (this.resourceXmlDoc != null && this.resourceXmlDoc.selectSingleNode("//Resources/SiteMap/Groups/Group[@Id='" + group + "']") != null) {
                    groupTitleTmp = this.resourceXmlDoc.selectSingleNode("//Resources/SiteMap/Groups/Group[@Id='" + group + "']/Titles/Title[@LCID='" + this.context.getOrgLcid() + "']/@Title");
                    if (groupTitleTmp != null)
                        groupTitle = groupTitleTmp.nodeValue;
                    else {
                        groupTitleTmp = this.resourceXmlDoc.selectSingleNode("//Resources/SiteMap/Groups/Group[@Id='" + group + "']/Titles/Title/@Title");
                        if (groupTitleTmp != null)
                            groupTitle = groupTitleTmp.nodeValue;
                    }
                }

                // If title wasn't found in resource xml get it from sitemap
                if (groupTitle == "") {
                    var groupTitleTmp = this.siteMapDoc.selectSingleNode("//SiteMap/Area[@Id='" + area + "']/Group[@Id='" + group + "']/Titles/Title[@LCID='" + this.context.getOrgLcid() + "']/@Title");
                    if (groupTitleTmp != null)
                        groupTitle = groupTitleTmp.nodeValue;
                    else
                        groupTitle = group;

                }

                var subAreas = this.siteMapDoc.selectNodes("//SiteMap/Area[@Id='" + area + "']/Group[@Id='" + group + "']/SubArea");

                var subAreaCount = subAreas.length;

                for (var s = 0; s < subAreaCount; s++) {

                    var subArea = subAreas[s].getAttribute("Id");

                    // Check if the item should be excluded
                    if (this.IsExcluded(area, group, subArea)) {

                        this.ProcessMenuItemActionComplete();

                        continue;
                    }


                    var imageIconUrl = null;
                    var subAreaTitle = "";

                    // Grab title value from local resource xml if present
                    if (this.resourceXmlDoc != null && this.resourceXmlDoc.selectSingleNode("//Resources/SiteMap/SubAreas/SubArea[@Id='" + subArea + "']") != null) {
                        subAreaTitleTmp = this.resourceXmlDoc.selectSingleNode("//Resources/SiteMap/SubAreas/SubArea[@Id='" + subArea + "']/Titles/Title[@LCID='" + this.context.getOrgLcid() + "']/@Title");
                        if (subAreaTitleTmp != null) {
                            subAreaTitle = subAreaTitleTmp.nodeValue;
                        }
                        else {
                            subAreaTitleTmp = this.resourceXmlDoc.selectSingleNode("//Resources/SiteMap/SubAreas/SubArea[@Id='" + subArea + "']/Titles/Title/@Title");
                            if (subAreaTitleTmp != null) {
                                subAreaTitle = subAreaTitleTmp.nodeValue;
                            }
                        }

                        // Grab icon if it exists
                        var subAreaImageTmp = this.resourceXmlDoc.selectSingleNode("//Resources/SiteMap/SubAreas/SubArea[@Id='" + subArea + "']/@Icon");
                        if (subAreaImageTmp != null)
                            imageIconUrl = subAreaImageTmp.nodeValue;

                    }

                    // If title wasn't found in resource xml get it from sitemap
                    if (subAreaTitle == "") {
                        var subAreaTitleTmp = this.siteMapDoc.selectSingleNode("//SiteMap/Area[@Id='" + area + "']/Group[@Id='" + group + "']/SubArea[@Id='" + subArea + "']/Titles/Title[@LCID='" + this.context.getOrgLcid() + "']/@Title");
                        if (subAreaTitleTmp != null)
                            subAreaTitle = subAreaTitleTmp.nodeValue;
                    }


                    var entityLogicalName = subAreas[s].getAttribute("Entity");

                    if ((subAreaTitle != null && subAreaTitle != "") || (entityLogicalName != null && entityLogicalName != "")) {

                        var url = subAreas[s].getAttribute("Url");
                        if (url == null) {
                            url = "/_root/homepage.aspx?etc=&sitemappath=" + encodeURIComponent(area + "|" + group + "|" + subArea);
                        }
                        else {
                            if (url.indexOf("?") == -1)
                                url += "?sitemappath=" + encodeURIComponent(area + "|" + group + "|" + subArea);
                            else
                                url += "&sitemappath=" + encodeURIComponent(area + "|" + group + "|" + subArea);
                        }

                        var title = subAreas[s].getAttribute("Title");
                        if (subAreaTitle == "")
                            subAreaTitle = title;

                        // Does the subArea have an Icon attribute
                        if (imageIconUrl == null && subAreas[s].getAttribute("Icon") != null)
                            imageIconUrl = subAreas[s].getAttribute("Icon");


                        var item = new DXTools.QuickView.MenuItem();
                        item.AreaId = area;
                        item.AreaTitle = areaTitle;
                        item.GroupId = group;
                        item.GroupTitle = groupTitle;
                        item.ItemId = subArea;
                        item.ItemTitle = subAreaTitle;
                        item.ItemTypeName = entityLogicalName;
                        item.Url = url;

                        if (imageIconUrl != null && imageIconUrl != "") {
                            item.ImageUrl = imageIconUrl.replace("$webresource:", this.context.getClientUrl() + "/WebResources/");

                            img = new Image();
                            img.src = item.ImageUrl;

                        }

                        this.menuTree.push(item);

                        if (entityLogicalName != null && entityLogicalName != "") {


                            if (this.IsSecurityEnabled()) {
                                // Add to call stack for validate ValidateUserPrivilegeToEntity function, This function removes menu items if the user doesn't have access.
                                this.processMenuItemCallStackCount = this.processMenuItemCallStackCount + 1;
                                this.ValidateUserPrivilegeToEntity(entityLogicalName);
                            }

                            var mdq = SDK.Metadata.Query;
                            var semp = mdq.SearchableAttributeMetadataProperties;
                            var emp = mdq.EntityMetadataProperties;

                            // Define entity properties
                            var entityProperties = new mdq.MetadataPropertiesExpression(false, [emp.LogicalName, emp.DisplayCollectionName, emp.IconLargeName, emp.IconMediumName, emp.IconSmallName, emp.ObjectTypeCode]);

                            // Define filter
                            var entityFilter = new mdq.MetadataFilterExpression(mdq.LogicalOperator.And);
                            entityFilter.addCondition(semp.LogicalName, mdq.MetadataConditionOperator.Equals, entityLogicalName);

                            // LabelQuery
                            var lq = new mdq.LabelQueryExpression([this.context.getOrgLcid()]);
                            var query = new mdq.EntityQueryExpression(entityFilter, entityProperties, null, null, lq);

                            // Retrieve the metadata and continues through other operations asynchronously 
                            // using the successCallback parameters containing the next steps.
                            this.GetMetadataChanges(
                                mdq,
                             query,
                             null, //No ClientVersionStamp passed the first time.
                             null, //No DeletedMetadataFilters are defined.
                            function (results) {

                                if (results != null && results.EntityMetadata != null && results.EntityMetadata.length > 0) {
                                    var entityData = results.EntityMetadata[0];

                                    var menuTreeCount = this.DXTools.QuickView.Menu.menuTree.length;
                                    for (var i = 0; i < menuTreeCount; i++) {

                                        //for (var i in this.DXTools.QuickView.Menu.menuTree) {


                                        // Checking this.DXTools.QuickView.Menu.menuTree[i].ItemTypeCode is populated allows this iteration to process the same entity more then once if it is is the sitemap multiple times.
                                        if (this.DXTools.QuickView.Menu.menuTree[i] != null && this.DXTools.QuickView.Menu.menuTree[i].ItemTypeCode == "" && this.DXTools.QuickView.Menu.menuTree[i].ItemTypeName == entityData.LogicalName) {

                                            this.DXTools.QuickView.Menu.menuTree[i].ItemTypeCode = entityData.ObjectTypeCode;
                                            if (this.DXTools.QuickView.Menu.menuTree[i].Url.indexOf("etc=&") != -1)
                                                this.DXTools.QuickView.Menu.menuTree[i].Url = this.DXTools.QuickView.Menu.menuTree[i].Url.replace("etc=", "etc=" + ((entityData.ObjectTypeCode != null) ? entityData.ObjectTypeCode : ""));

                                            // Get title if it doesn't exist from sitemap already
                                            if ((this.DXTools.QuickView.Menu.menuTree[i].ItemTitle == null | this.DXTools.QuickView.Menu.menuTree[i].ItemTitle == "") && entityData.DisplayCollectionName != null && entityData.DisplayCollectionName.UserLocalizedLabel != null) {
                                                this.DXTools.QuickView.Menu.menuTree[i].ItemTitle = entityData.DisplayCollectionName.UserLocalizedLabel.Label;
                                            }

                                            // Only add image if it isn't already specified from resource xml
                                            if (this.DXTools.QuickView.Menu.menuTree[i].ImageUrl == null || this.DXTools.QuickView.Menu.menuTree[i].ImageUrl == "") {

                                                if (entityData.IconMediumName != null || entityData.IconLargeName != null || entityData.IconSmallName != null) {
                                                    if (entityData.IconMediumName != null)
                                                        this.DXTools.QuickView.Menu.menuTree[i].ImageUrl = this.DXTools.QuickView.Menu.context.getClientUrl() + "/WebResources/" + entityData.IconMediumName;
                                                    else if (entityData.IconLargeName != null)
                                                        this.DXTools.QuickView.Menu.menuTree[i].ImageUrl = this.DXTools.QuickView.Menu.context.getClientUrl() + "/WebResources/" + entityData.IconLargeName;
                                                    else if (entityData.IconSmallName != null)
                                                        this.DXTools.QuickView.Menu.menuTree[i].ImageUrl = this.DXTools.QuickView.Menu.context.getClientUrl() + "/WebResources/" + entityData.IconSmallName;

                                                    img = new Image();
                                                    img.src = this.DXTools.QuickView.Menu.menuTree[i].ImageUrl;

                                                }
                                                else {
                                                    // Check if the sitemap has an Icon
                                                    var subAreaIcon = this.DXTools.QuickView.Menu.siteMapDoc.selectSingleNode("//SiteMap/Area[@Id='" + this.DXTools.QuickView.Menu.menuTree[i].AreaId + "']/Group[@Id='" + this.DXTools.QuickView.Menu.menuTree[i].GroupId + "']/SubArea[@Id='" + this.DXTools.QuickView.Menu.menuTree[i].ItemId + "']/@Icon");
                                                    if (subAreaIcon != null && subAreaIcon.nodeValue != null) {
                                                        this.DXTools.QuickView.Menu.menuTree[i].ImageUrl = subAreaIcon.nodeValue.replace("$webresource:", this.DXTools.QuickView.Menu.context.getClientUrl() + "/WebResources/");
                                                        img = new Image();
                                                        img.src = this.DXTools.QuickView.Menu.menuTree[i].ImageUrl;
                                                    }
                                                }
                                            }

                                            break;
                                        }
                                    }
                                }


                                // All menu Items processed so exit and display them      
                                this.DXTools.QuickView.Menu.ProcessMenuItemActionComplete();

                            },
                             function (error) {
                                 this.DXTools.QuickView.Menu.ProcessMenuItemActionComplete();
                             }
                            );
                        }
                        else {
                            this.ProcessMenuItemActionComplete();
                        }
                    }
                    else {

                        this.ProcessMenuItemActionComplete();
                    }
                }
            }
        }
    },


    //
    // Checks the config exclusions held in the Config xml agains the supplied items area, group and subarea id's
    //
    IsExcluded: function (area, group, subarea) {

        var excluded = false;

        if (this.configXmlDoc != null) {
            if (area != null && this.configXmlDoc.selectSingleNode("//Config/Exclusions/Areas/Area[@Id='" + area + "']"))
                excluded = true;
            else if (group != null && this.configXmlDoc.selectSingleNode("//Config/Exclusions/Groups/Group[@Id='" + group + "']"))
                excluded = true;
            if (subarea != null && this.configXmlDoc.selectSingleNode("//Config/Exclusions/SubAreas/SubArea[@Id='" + subarea + "']"))
                excluded = true;
        }
        return excluded;
    },


    //
    // Retreives the metadata based on the supplied query expression criteria
    //
    GetMetadataChanges: function (MDQuery, entityQueryExpression, clientVersionStamp, deletedMetadataFilter, successCallBack, errorCallback) {
        //Initialize a SDK.Metadata.Query.RetrieveMetadataChangesRequest object.
        var retrieveMetadataChangesRequest = new MDQuery.RetrieveMetadataChangesRequest(entityQueryExpression, clientVersionStamp, deletedMetadataFilter);
        //Execute the request passing the successCallBack and errorCallback functions through.
        MDQuery.RetrieveMetadataChanges(retrieveMetadataChangesRequest, successCallBack, errorCallback);
    },


    //
    // Convert menu item objects to xml and display as html using xsl
    //
    DisplayMenuItems: function () {

        var xml = "";
        var xsltFileName = "";

        switch (qvmLayout) {
            case "Normal":
                xml = this.ConvertMenuItemsToXML();
                xsltFileName = "QuickViewMenuLayout.xslt";
                break;
            case "Compact":
                xml = this.ConvertMenuItemsToXMLCompact();
                xsltFileName = "QuickViewMenuLayoutCompact.xslt";
                break;
            default:
                xml = this.ConvertMenuItemsToXML();
                xsltFileName = "QuickViewMenuLayout.xslt";
                break;
        }

        var xmlDoc = null;
        if (window.ActiveXOBject || "ActiveXObject" in window) {
            xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
            xmlDoc.async = false;
            xmlDoc.loadXML(xml);
        }
        else // Internet Explorer
        {
            parser = new DOMParser();
            xmlDoc = parser.parseFromString(xml, "text/xml");
        }


        var xsl = this.LoadXMLDoc(xsltFileName);

        var html = this.TransformToHtmlText(xmlDoc, xsl);

        // code for IE and other browsers that support inner HTML
        if (document.getElementById("uxMenu").innerHTML != null) {

            document.getElementById("uxMenu").innerHTML = html;
        }            // code for Mozilla, Firefox, Opera, etc.
        else if (document.implementation && document.implementation.createDocument) {
            document.getElementById("uxMenu").appendChild(html);
        }
        else {
            try {
                var el = document.getElementById("uxMenu");
                el.innerHTML = html;
            } catch (ex)
            { }
        }
    },


    //
    // Load xml document from url
    //
    LoadXMLDoc: function (url) {
        if (window.ActiveXOBject || "ActiveXObject" in window) {
            xhttp = new ActiveXObject("Msxml2.XMLHTTP.3.0");
        }
        else {
            xhttp = new XMLHttpRequest();
        }
        xhttp.open("GET", url, false);
        xhttp.send("");
        return xhttp.responseXML;
    },


    //
    // Convert menu item objects to XML
    //
    ConvertMenuItemsToXML: function () {

        var xmlDoc = null;
        if (window.ActiveXOBject || "ActiveXObject" in window)
            xmlDoc = new ActiveXObject('Msxml2.DOMDocument.6.0');
        else
            xmlDoc = document.implementation.createDocument("", "", null);

        var AreaXmlDom = xmlDoc.createElement("MENU");

        var areaId = "";
        var AreaNode = null;

        var menuTreeCount = this.menuTree.length;
        for (var i = 0; i < menuTreeCount; i++) {

            //for (var i in this.menuTree) {

            if (this.menuTree[i] == null)
                continue;


            if (areaId != this.menuTree[i].AreaId) {

                if (AreaNode != null)
                    AreaXmlDom.appendChild(AreaNode);

                areaId = this.menuTree[i].AreaId;
                AreaNode = xmlDoc.createElement("MenuArea");
                AreaNode.setAttribute("Title", this.menuTree[i].AreaTitle)
                AreaNode.setAttribute("Url", this.menuTree[i].Url)
            }

            if (this.menuTree[i].ItemTitle != null && this.menuTree[i].ItemTitle != "") {
                var menuItemNode = xmlDoc.createElement("MenuAreaItem");

                menuItemNode.setAttribute("ItemId", this.menuTree[i].ItemId)
                //AreaNode.appendChild(menuItemNode);
                menuItemNode.setAttribute("Title", this.menuTree[i].ItemTitle)
                //AreaNode.appendChild(menuItemNode);
                menuItemNode.setAttribute("Url", this.menuTree[i].Url)
                // AreaNode.appendChild(menuItemNode);
                menuItemNode.setAttribute("ImageUrl", this.menuTree[i].ImageUrl)
                AreaNode.appendChild(menuItemNode);
            }
        }

        // Final Area append
        if (AreaNode != null)
            AreaXmlDom.appendChild(AreaNode);

        return this.GetXMLStringFromDocument(AreaXmlDom);


    },

    //
    // Convert menu item objects to XML
    //
    ConvertMenuItemsToXMLCompact: function () {

        var xmlDoc = null;
        if (window.ActiveXOBject || "ActiveXObject" in window)
            xmlDoc = new ActiveXObject('Msxml2.DOMDocument.6.0');
        else
            xmlDoc = document.implementation.createDocument("", "", null);

        var AreaXmlDom = xmlDoc.createElement("MENU");

        var rowCount = 0;
        var AreaNode = null;
        var menuItemList = "";




        this.menuTree.sort(function (a, b) {
            if (a.ItemTitle < b.ItemTitle)
                return -1
            if (a.ItemTitle > b.ItemTitle)
                return 1
            return 0

            return a.ItemTitle > b.ItemTitle;
        });


        var menuTreeCount = this.menuTree.length;
        for (var i = 0; i < menuTreeCount; i++) {


            if (this.menuTree[i] == null)
                continue;

            if (rowCount == 0) {
                AreaNode = xmlDoc.createElement("MenuArea");
            }
            else if (rowCount > 9) {

                rowCount = 0;

                if (AreaNode != null)
                    AreaXmlDom.appendChild(AreaNode);

                AreaNode = xmlDoc.createElement("MenuArea");

            }

            if (this.menuTree[i].ItemTitle != null && this.menuTree[i].ItemTitle != "") {

                if (menuItemList.indexOf(this.menuTree[i].ItemTitle) == -1) {
                    menuItemList += this.menuTree[i].ItemTitle + "|";

                    var menuItemNode = xmlDoc.createElement("MenuAreaItem");
                    menuItemNode.setAttribute("ItemId", this.menuTree[i].ItemId)
                    menuItemNode.setAttribute("Title", this.menuTree[i].ItemTitle)
                    menuItemNode.setAttribute("Url", this.menuTree[i].Url)
                    menuItemNode.setAttribute("ImageUrl", this.menuTree[i].ImageUrl)
                    AreaNode.appendChild(menuItemNode);

                    rowCount++;
                }
            }

        }


        // Final Area append
        if (AreaNode != null)
            AreaXmlDom.appendChild(AreaNode);

        return this.GetXMLStringFromDocument(AreaXmlDom);


    },


    //
    // Transform xml doc and xsl to html
    //
    TransformToHtmlText: function (xmlDoc, xsltDoc) {
        // 1.
        if (typeof (XSLTProcessor) != "undefined") {
            var xsltProcessor = new XSLTProcessor();
            xsltProcessor.importStylesheet(xsltDoc);
            var xmlFragment = xsltProcessor.transformToFragment(xmlDoc, document);

            if (typeof (GetXmlStringFromXmlDoc) != "undefined") {
                return GetXmlStringFromXmlDoc(xmlFragment);
            }
            else {
                // chrome friendly

                // get a xml serializer object
                var xmls = new XMLSerializer();

                // convert dom into string
                var sResult = xmls.serializeToString(xmlFragment);
                //extract contents of transform iix node if it is present
                if (sResult.indexOf("<transformiix:result") > -1) {
                    sResult = sResult.substring(sResult.indexOf(">") + 1, sResult.lastIndexOf("<"));
                }
                return sResult;
            }
        }
        // 2.
        if (typeof (xmlDoc.transformNode) != "undefined") {
            return xmlDoc.transformNode(xsltDoc);
        }
        else {

            var activeXOb = null;
            try { activeXOb = new ActiveXObject("Msxml2.XSLTemplate"); } catch (ex) { }

            try {
                // 3
                if (activeXOb) {
                    var xslt = activeXOb;
                    var xslDoc = new ActiveXObject("Msxml2.FreeThreadedDOMDocument");
                    xslDoc.loadXML(xsltDoc.xml);
                    xslt.stylesheet = xslDoc;
                    var xslProc = xslt.createProcessor();
                    xslProc.input = xmlDoc;
                    xslProc.transform();

                    return xslProc.output;
                }
            }
            catch (e) {
                // 4
                alert("The type [XSLTProcessor] and the function [XmlDocument.transformNode] are not supported by this browser, can't transform XML document to HTML string!");
                return null;
            }

        }
    },

    ConvertXmlStringToDocument: function (xmlString) {
        var xmlDoc = null;
        if (window.ActiveXOBject || "ActiveXObject" in window) {
            xmlDoc = new ActiveXObject('Msxml2.DOMDocument.6.0');
            xmlDoc.loadXML(xmlString);
        } else {
            var parser = new DOMParser();
            xmlDoc = parser.parseFromString(xmlString, "text/xml");
        }
        return xmlDoc;
    },
    GetXMLStringFromDocument: function (Doc) {
        var xml = null;

        if (Doc.xml)
            xml = Doc.xml;
        else {
            var serializer = new XMLSerializer();
            xml = serializer.serializeToString(Doc);

        }
        return xml;
    },

    RetrieveConfigAndResourceXML: function () {
        var config = this.LoadXMLDoc("QuickViewMenuConfig.xml");
        if (window.ActiveXOBject || "ActiveXObject" in window) {
            if (config != null && config.xml != null) {
                this.configXmlDoc = this.ConvertXmlStringToDocument(config.xml);
            }
        }
        else {
            if (config != null) {
                this.configXmlDoc = config.documentElement;
            }
        }

        var resource = this.LoadXMLDoc("QuickViewMenuResources.xml");
        if (window.ActiveXOBject || "ActiveXObject" in window) {
            if (resource != null && resource.xml != null) {
                this.resourceXmlDoc = this.ConvertXmlStringToDocument(resource.xml);
            }
        }
        else {
            if (resource != null) {
                this.resourceXmlDoc = resource.documentElement;
            }
        }

        this.LoadActionComplete();

    },



    RetrieveSiteMap: function () {
        // Retrieve sitemap xml
        //
        SDK.REST.retrieveMultipleRecords("SiteMap", "$select=SiteMapXml",
                function (data) {

                    if (data[0] != null) {
                        var siteMapXml = data[0].SiteMapXml;

                        if (siteMapXml != null && siteMapXml != "") {

                            // Store sitemap Document
                            this.DXTools.QuickView.Menu.siteMapDoc = this.DXTools.QuickView.Menu.ConvertXmlStringToDocument(siteMapXml);

                            // Call load action complete
                            this.DXTools.QuickView.Menu.LoadActionComplete();
                        }

                    }
                },
                function (error) {
                    alert(error);

                }, function () { });
    },



    RetrieveUserPrivileges: function () {

        var soapXmlDoc = this.LoadXMLDoc("RetrieveUserPrivilegesSoapXml.xml");
        var envelope = soapXmlDoc.selectSingleNode("//s:Envelope");
        var envelopeXml = this.GetXMLStringFromDocument(envelope);

        //var soapXml = this.GetXMLStringFromDocument(soapXmlDoc);


        if (envelopeXml != null) {
            var envelopeXml = envelopeXml.replace("@UserId", this.context.getUserId());


            var req = new XMLHttpRequest();
            req.open("POST", this.context.getClientUrl() + "/XRMServices/2011/Organization.svc/web", true);
            req.setRequestHeader("Accept", "application/xml, text/xml, */*");
            req.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
            req.setRequestHeader("SOAPAction", "http://schemas.microsoft.com/xrm/2011/Contracts/Services/IOrganizationService/Execute");
            req.onreadystatechange = function () {
                if (this.readyState == 4 /* complete */) {
                    if (this.status == 200 || this.status == 204 || this.status == 1223) {
                        //successCallback();

                        DXTools.QuickView.Menu.userPrivilegesDoc = DXTools.QuickView.Menu.ConvertXmlStringToDocument(this.responseText);

                        // Call load action complete
                        DXTools.QuickView.Menu.LoadActionComplete();
                    }
                    else {
                        DXTools.QuickView.Menu.LoadActionComplete();
                    }

                }
            };
            req.send(envelopeXml);

        }
    },

    ValidateUserPrivilegeToEntity: function (EntityName) {

        if (this.userPrivilegesDoc == null) {
            this.ProcessMenuItemActionComplete();
            return;
        }

        // Prv = prvReadContact
        var prvName = "prvRead" + EntityName;

        SDK.REST.retrieveMultipleRecords("Privilege", "$select=PrivilegeId&$filter=Name eq '" + prvName + "'&$top=1",
                function (data) {

                    if (data[0] != null) {
                        var privId = data[0].PrivilegeId;

                        if (privId != null && privId != "") {
                            // Check if user has priv

                            //try{
                            //    this.DXTools.QuickView.Menu.userPrivilegesDoc.setProperty('SelectionNamespaces', "xmlns:b='http://schemas.microsoft.com/crm/2011/Contracts'");
                            //}catch(ex){};

                            var userPrivLookupResult = this.DXTools.QuickView.Menu.userPrivilegesDoc.selectSingleNode("//*[local-name() = 'PrivilegeId'][text()='" + privId + "'] ");
                            if (userPrivLookupResult == null) {
                                // No priv found so do somehting

                                var menuTreeCount = this.DXTools.QuickView.Menu.menuTree.length;
                                for (var i = 0; i < menuTreeCount; i++) {

                                    // for (var i in this.DXTools.QuickView.Menu.menuTree) {

                                    // Checking this.DXTools.QuickView.Menu.menuTree[i].ItemTypeCode is populated allows this iteration
                                    // to process the same entity more then once if it is is the sitemap maultiple times.
                                    if (this.DXTools.QuickView.Menu.menuTree[i] != null && this.DXTools.QuickView.Menu.menuTree[i].ItemTypeName == EntityName) {
                                        this.DXTools.QuickView.Menu.menuTree[i] = null;
                                        break;
                                    }
                                }
                            }

                        }
                    }

                    this.DXTools.QuickView.Menu.ProcessMenuItemActionComplete();

                },
                function (error) {
                    this.DXTools.QuickView.Menu.ProcessMenuItemActionComplete();

                }, function () {

                });


    },

    //
    // Navigate to url within the existing CRM window.
    //
    // NOTE: Uses unsupported CRM 2013 internal raiseNavigationRequest function to
    // mimic CRM's sitemap navigation functionlity
    //
    //
    LoadUrl: function (link) {
        var url = "";

        if (link.Url) {
            url = link.Url;
        }
        else if (link.attributes["url"] != null && link.attributes["url"].nodeValue != null && link.attributes["url"].nodeValue != "") {
            url = link.attributes["url"].nodeValue;
        }


        var o = new Object();
        o.uri = url;
        if (window.top && window.top.document.getElementById("navBar") && window.top.document.getElementById("navBar").control.raiseNavigateRequest)
            window.top.document.getElementById("navBar").control.raiseNavigateRequest(o);
        else {
            // load the url here using CRM SDK url forms and views
        }

    }
    ,

    __namespace: true
};
